package com.mcp.converter.domain.report.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.mcp.converter.domain.checker.CompatibilityResult;
import com.mcp.converter.domain.checker.IncompatibilityDetail;
import com.mcp.converter.domain.checker.IncompatiblePoint;
import com.mcp.converter.domain.converter.ConversionDetail;
import com.mcp.converter.domain.converter.ConversionResult;
import com.mcp.converter.domain.report.IncompatibilityReport;
import com.mcp.converter.domain.report.IncompatibilityReportDetail;
import com.mcp.converter.domain.report.ReportGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * 报告生成器实现类
 * 负责生成不兼容分析报告
 */
@Service
public class ReportGeneratorImpl implements ReportGenerator {

    @Autowired
    private TemplateEngine templateEngine;

    @Override
    public IncompatibilityReport generate(CompatibilityResult compatibilityResult, ConversionResult conversionResult) {
        if (compatibilityResult == null) {
            throw new IllegalArgumentException("兼容性检测结果不能为空");
        }

        IncompatibilityReport report = new IncompatibilityReport();

        // 设置报告ID
        report.setReportId("report-" + new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date()) + "-" + UUID.randomUUID().toString().substring(0, 8));

        // 设置原始SQL
        if (conversionResult != null) {
            report.setOriginalSQL(conversionResult.getOriginalSQL());
            report.setConvertedSQL(conversionResult.getConvertedSQL());
        }

        // 设置兼容性信息
        report.setCompatible(compatibilityResult.isCompatible());
        report.setIncompatiblePointCount(compatibilityResult.getIncompatiblePointCount());

        // 设置转换信息
        if (conversionResult != null) {
            report.setConvertedCount(conversionResult.getConversionDetailCount());
        }

        // 添加不兼容详情
        if (compatibilityResult.getIncompatiblePoints() != null) {
            for (IncompatiblePoint incompatiblePoint : compatibilityResult.getIncompatiblePoints()) {
                IncompatibilityReportDetail detail = createReportDetail(incompatiblePoint, conversionResult);
                if (detail != null) {
                    report.addDetail(detail);
                }
            }
        }

        return report;
    }

    @Override
    public ExportResult export(IncompatibilityReport report, ReportFormat format) {
        if (report == null) {
            throw new IllegalArgumentException("报告不能为空");
        }

        try {
            switch (format) {
                case JSON:
                    return exportToJson(report);
                case HTML:
                    return exportToHtml(report);
                case PDF:
                    return exportToPdf(report);
                default:
                    return new ExportResult(false, "不支持的报告格式: " + format);
            }
        } catch (Exception e) {
            return new ExportResult(false, "导出报告失败: " + e.getMessage());
        }
    }

    /**
     * 创建报告详情
     *
     * @param point            不兼容点
     * @param conversionResult 转换结果
     * @return 报告详情
     */
    private IncompatibilityReportDetail createReportDetail(IncompatiblePoint point, ConversionResult conversionResult) {
        if (point == null) {
            return null;
        }

        IncompatibilityReportDetail detail = new IncompatibilityReportDetail();

        // 设置基本信息
        detail.setType(point.getType());
        detail.setName(point.getName() != null ? point.getName() : "");
        detail.setValue(point.getValue() != null ? point.getValue() : "");

        // 设置转换建议和转换状态
        detail.setSuggestion("Manual review required");
        detail.setConverted(false);
        detail.setConvertedContent("");

        // 设置位置信息
        if (point.getPosition() != null) {
            IncompatibilityReportDetail.Position position =
                    new IncompatibilityReportDetail.Position(point.getPosition().getLine(),
                            point.getPosition().getColumn(), point.getPosition().getStartIndex(),
                            point.getPosition().getEndIndex());
            detail.setPosition(position);
        }

        // 创建不兼容点详情
        IncompatibilityDetail incompatibilityDetail = new IncompatibilityDetail();
        incompatibilityDetail.setIncompatiblePoint(point);

        if (incompatibilityDetail != null) {
            detail.setReason(incompatibilityDetail.getReason());
            detail.setImpact(incompatibilityDetail.getImpact());
            detail.setSeverity(incompatibilityDetail.getSeverity());

            // Set converted status based on detail
            detail.setConverted(conversionResult != null && conversionResult.isSuccessful());
            if (detail.isConverted() && conversionResult != null && conversionResult.getConvertedSQL() != null) {
                detail.setConvertedContent(conversionResult.getConvertedSQL());
            }
        }

        // 设置转换信息
        if (conversionResult != null) {
            for (ConversionDetail conversionDetail : conversionResult.getConversionDetails()) {
                if (conversionDetail.getType() == point.getType() && (conversionDetail.getOriginal().contains(point.getName()) || conversionDetail.getOriginal().contains(point.getValue()))) {
                    detail.setConverted(conversionDetail.getConverted().isEmpty());
                    detail.setConverted(true);
                    break;
                }
            }
        }

        return detail;
    }

    /**
     * 导出为JSON
     *
     * @param report 报告
     * @return 导出结果
     */
    private ExportResult exportToJson(IncompatibilityReport report) {
        if (report == null) {
            return new ExportResult(false, "报告不能为空");
        }

        try {
            // 使用Jackson将报告转换为JSON
            ObjectMapper mapper = new ObjectMapper();
            String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(report);

            // 创建临时文件
            File tempFile = File.createTempFile("report_", ".json");

            // 写入JSON到临时文件
            try (FileWriter writer = new FileWriter(tempFile)) {
                writer.write(json);
            }

            // 读取文件内容到字节数组
            byte[] fileContent = Files.readAllBytes(tempFile.toPath());

            // 删除临时文件
            tempFile.delete();

            return new ExportResult(true, "JSON报告生成成功", fileContent);

        } catch (Exception e) {
            return new ExportResult(false, "导出JSON报告失败: " + e.getMessage());
        }
    }

    /**
     * 导出为HTML
     *
     * @param report 报告
     * @return 导出结果
     */
    private ExportResult exportToHtml(IncompatibilityReport report) {
        try {
            // 创建Thymeleaf上下文
            Context context = new Context();
            context.setVariable("report", report);

            // 处理模板
            String htmlContent = templateEngine.process("report-template", context);

            // 保存到临时文件
            File tempFile = File.createTempFile("report_", ".html");
            try (FileWriter writer = new FileWriter(tempFile)) {
                writer.write(htmlContent);
            }

            // 读取文件内容到字节数组
            byte[] fileContent = Files.readAllBytes(tempFile.toPath());

            // 删除临时文件
            tempFile.delete();

            return new ExportResult(true, "报告已成功生成", fileContent);
        } catch (Exception e) {
            return new ExportResult(false, "导出HTML报告失败: " + e.getMessage());
        }
    }

    /**
     * 导出为PDF
     *
     * @param report 报告
     * @return 导出结果
     */
    private ExportResult exportToPdf(IncompatibilityReport report) {
        try {
            // 首先导出为HTML
            ExportResult htmlResult = exportToHtml(report);
            if (!htmlResult.isSuccess()) {
                return htmlResult;
            }

            // 创建临时PDF文件
            File tempPdfFile = File.createTempFile("report_", ".pdf");

            // 使用iText将HTML转换为PDF
            try (FileOutputStream fos = new FileOutputStream(tempPdfFile)) {
                Document document = new Document();
                PdfWriter writer = PdfWriter.getInstance(document, fos);
                document.open();

                // 添加HTML内容
                XMLWorkerHelper.getInstance().parseXHtml(writer, document,
                        new ByteArrayInputStream(htmlResult.getContent()));

                document.close();
            }

            // 读取PDF文件内容到字节数组
            byte[] pdfContent = Files.readAllBytes(tempPdfFile.toPath());

            // 删除临时PDF文件
            tempPdfFile.delete();

            return new ExportResult(true, "报告已成功生成", pdfContent);
        } catch (Exception e) {
            return new ExportResult(false, "导出PDF报告失败: " + e.getMessage());
        }
    }
}